#include "kernel/vfs/fat32.h"
#include "kernel/driver/disk.h"
#include "libs/errno.h"
#include "kernel/task/task.h"
#include "libs/stdio.h"
#include "libs/path.h"

Fat32FS* Fat32FS::fat32m = NULL;
Fat32FS::Fat32FS(/* args */)
{

   fat32m = this;
   DiskPartitionTable DPT;
   DirEntry* denty = NULL;
   uint8_t buffer[512];
   memset(buffer,0,512);

   name = "fat32";
   fsFlag = 0;

   VFSMANAGER->addFilesystem(this);
   DISKMANAGER->readDisk(0x1,0,1,buffer);
   rootSb =  VFSMANAGER->mountFs("fat32",buffer);
	


//    LOG_INFO("FAT32 FSInfo\n\tFSI_LeadSig:%#018lx\n\tFSI_StrucSig:%#018lx\n\tFSI_Free_Count:%#018lx\n",fat32_fsinfo.FSI_LeadSig,fat32_fsinfo.FSI_StrucSig,fat32_fsinfo.FSI_Free_Count);

   delete denty;



}

Fat32FS::~Fat32FS()
{


}


DirEntry* Fat32FS::pathSearch(char* name,uint64_t flags){



   char * tmpname = NULL;
	int tmpnamelen = 0;
	DirEntry* parent = rootSb->root;
	DirEntry* path = NULL;

	while(*name == '/')
		name++;

	if(!*name)
		return parent;



	for(;;)
	{
		tmpname = name;
		while(*name && (*name != '/'))
			name++;
		tmpnamelen = name - tmpname;


		path = new DirEntry;
		path->name = new char[tmpnamelen + 1];
		memset(path->name,0,tmpnamelen + 1);
		memcpy(tmpname,path->name,tmpnamelen);
		path->nameLength = tmpnamelen;
		
		DirEntry* tempPath = parent->dirInode->lookup(parent->dirInode,path);
      
		if(tempPath == NULL)
		{
			LOG_ERROR("can not find file or dir:%s\n",path->name);
			delete path;
			return NULL;
		}

		list_init(&path->childNode);
		list_init(&path->subdirsList);
		path->parent = parent;
		list_add_to_behind(&parent->subdirsList,&path->childNode);

		if(!*name)
			goto last_component;
		while(*name == '/')
			name++;
		if(!*name)
			goto last_slash;

		parent = path;
	}

last_slash:
last_component:
	if(flags & 1)
	{
		return parent;
	}

	return path;

}

void Fat32FS::createFile(char* path,uint64_t attribute,uint64_t type)
{	
	Path stringPath(path);
	
	auto denty =  pathSearch(stringPath.dir(),1);

	if(!denty)
	{
		LOG_ERROR("no this dir!\n");
		return;
	}

	auto fsbi = (FAT32_sb_info*)denty->dirInode->sb->privateSbInfo;
	DirEntry* pfileDentry = new FAT32DirEntry();
	pfileDentry->name = stringPath.file();
	pfileDentry->nameLength = strlen(pfileDentry->name);

	auto tempDentry = denty->dirInode->lookup(denty->dirInode,pfileDentry);

	if(tempDentry)
	{
		LOG_ERROR("file is have exist!\n");
		return;
	}

	tempDentry  =  denty->dirInode->create(denty,path,attribute);


	if(!tempDentry)
	{

		LOG_ERROR("file create faild\n");

	}

	if(type == FS_ATTR_DEVICE)
	{

		auto fnodeinfo = (FAT32_inode_info*)tempDentry->dirInode->privateIndexInfo;
		fnodeinfo->first_cluster |= 0xf0000000;
		tempDentry->dirInode->sb->writeInode(tempDentry->dirInode);

	}

}





uint32_t Fat32FS::readFATEntry(FAT32_sb_info* fsbi,uint32_t fatEntry){


   uint32_t buf[128];
   memset(buf,0,512);
   DISKMANAGER->readDisk(0x1,fsbi->FAT1_firstsector + (fatEntry >> 7),1,(uint8_t*)buf);
   return (buf[fatEntry & 0x7f] & 0x0fffffff);

}
uint64_t Fat32FS::writeFATEntry(FAT32_sb_info* fsbi,uint32_t fatEntry,uint32_t value){


   uint32_t buf[128];
   memset(buf,0,512);
   DISKMANAGER->readDisk(0x1,fsbi->FAT1_firstsector + (fatEntry >> 7),1,(uint8_t*)buf);
   buf[fatEntry & 0x7f] = (buf[fatEntry & 0x7f] & 0xf0000000) | (value & 0x0fffffff);
   for(int i = 0; i< fsbi->NumFATs;i++){
   	DISKMANAGER->writeDisk(0x1,fsbi->FAT1_firstsector + i * fsbi->sector_per_FAT + (fatEntry >> 7),1,(uint8_t*)buf);
   }
   return 1;

}

uint64_t Fat32FS::findAvailableCluster(FAT32_sb_info* fsbi)
{
	
	int fatEntry;
	uint64_t sectorPerFat = fsbi->sector_per_FAT;
	uint32_t buf[128];

	for (size_t i = 0; i < sectorPerFat; i++)
	{
		/* code */
		memset(buf,0,512);
		DISKMANAGER->readDisk(0x1,fsbi->FAT1_firstsector + i,1,(uint8_t*)(buf));

		for (size_t j = 0; j < 128; j++)
		{

			/* code */
			if((buf[j] & 0x0fffffff) == 0){

				return (i << 7) + j;

			}
		}

		
	}

	return 0;
	


}

SuperBlock* Fat32FS::readSuperBlock(void* buf)
{
	

	SuperBlock* sbp= new FAT32SuperBlock();
	FAT32_BootSector* fbs = NULL;
	FAT32_inode_info* finode = NULL;
	FAT32_sb_info * fsbi = NULL;

//fat32 super block


//fat32 boot sector
	fbs = (FAT32_BootSector *)buf;
	fsbi = (FAT32_sb_info*)sbp->privateSbInfo;	
	fsbi->start_sector =0;
	fsbi->sector_count = 0;
	fsbi->sector_per_cluster = fbs->BPB_SecPerClus;
	fsbi->bytes_per_cluster = fbs->BPB_SecPerClus * fbs->BPB_BytesPerSec;
	fsbi->bytes_per_sector = fbs->BPB_BytesPerSec;
	fsbi->Data_firstsector = 0 + fbs->BPB_RsvdSecCnt + fbs->BPB_FATSz32 * fbs->BPB_NumFATs;
	fsbi->FAT1_firstsector = 0 + fbs->BPB_RsvdSecCnt;
	fsbi->sector_per_FAT = fbs->BPB_FATSz32;
	fsbi->NumFATs = fbs->BPB_NumFATs;
	fsbi->fsinfo_sector_infat = fbs->BPB_FSInfo;
	fsbi->bootsector_bk_infat = fbs->BPB_BkBootSec;	

// fat32 fsinfo sector
	
	DISKMANAGER->readDisk(0x1,fbs->BPB_FSInfo,1,(uint8_t*)fsbi->fat_fsinfo);

// root directory





// index node
	
	sbp->root->dirInode->fileSize = 0;
	//多大的空间
	sbp->root->dirInode->blocks = (sbp->root->dirInode->fileSize + fsbi->bytes_per_cluster - 1) / fsbi->bytes_per_sector;
	sbp->root->dirInode->attribute = FS_ATTR_DIR;
	sbp->root->dirInode->sb = sbp;



// fat32 root inode

	finode = (FAT32_inode_info*)sbp->root->dirInode->privateIndexInfo;
	finode->first_cluster = fbs->BPB_RootClus;
	finode->dentry_location = 0;
	finode->dentry_position = 0;
	finode->create_date = 0;
	finode->write_date = 0;
	finode->write_time = 0;
	finode->create_time = 0;


	return sbp;

}




DirEntry* FAT32IndexNode::lookup(IndexNode * parent_inode,DirEntry * dest_dentry)
{
	

	
 FAT32_inode_info* finode = (FAT32_inode_info*)parent_inode->privateIndexInfo;
    FAT32_sb_info* fsbi = (FAT32_sb_info*)parent_inode->sb->privateSbInfo;



	int i = 0,j = 0,x = 0;
	FAT32_Directory *tmpdentry = NULL;
    FAT32_LongDirectory *tmpldentry = NULL;

    uint8_t* buf = new uint8_t[fsbi->bytes_per_cluster];
    memset(buf,0,fsbi->bytes_per_cluster);
    int64_t cluster = finode->first_cluster;
next_cluster:
	int64_t sector = fsbi->Data_firstsector + (cluster - 2) * fsbi->sector_per_cluster;


	if(!DISKMANAGER->readDisk(0x1,sector,1,buf))
	{
		LOG_ERROR("FAT32 FS(lookup) read disk ERROR!!!!!!!!!!\n");
		delete buf;
		return NULL;
	}
    
	tmpdentry = (FAT32_Directory *)buf;

	for(i = 0;i < fsbi->bytes_per_cluster;i+= 32,tmpdentry++)
	{
		

		if(tmpdentry->DIR_Attr == ATTR_LONG_NAME)
			continue;
		if(tmpdentry->DIR_Name[0] == 0xe5 || tmpdentry->DIR_Name[0] == 0x00 || tmpdentry->DIR_Name[0] == 0x05)
			continue;

		tmpldentry = (struct FAT32_LongDirectory *)tmpdentry-1;
		j = 0;

		//long file/dir name compare
		while(tmpldentry->LDIR_Attr == ATTR_LONG_NAME && tmpldentry->LDIR_Ord != 0xe5)
		{
			for(x=0;x<5;x++)
			{
				if(j>dest_dentry->nameLength && tmpldentry->LDIR_Name1[x] == 0xffff)
					continue;
				else if(j>dest_dentry->nameLength || tmpldentry->LDIR_Name1[x] != (unsigned short)(dest_dentry->name[j++]))
					goto continue_cmp_fail;
			}
			for(x=0;x<6;x++)
			{
				if(j>dest_dentry->nameLength && tmpldentry->LDIR_Name2[x] == 0xffff)
					continue;
				else if(j>dest_dentry->nameLength || tmpldentry->LDIR_Name2[x] != (unsigned short)(dest_dentry->name[j++]))
					goto continue_cmp_fail;
			}
			for(x=0;x<2;x++)
			{
				if(j>dest_dentry->nameLength && tmpldentry->LDIR_Name3[x] == 0xffff)
					continue;
				else if(j>dest_dentry->nameLength || tmpldentry->LDIR_Name3[x] != (unsigned short)(dest_dentry->name[j++]))
					goto continue_cmp_fail;
			}

			if(j>=dest_dentry->nameLength)
			{
				goto find_lookup_success;
			}

			tmpldentry --;
		}
      
		//short file/dir base name compare
		j = 0;
		for(x=0;x<8;x++)
		{
			switch(tmpdentry->DIR_Name[x])
			{
				case ' ':
					if(!(tmpdentry->DIR_Attr & ATTR_DIRECTORY))
					{
						if(dest_dentry->name[j]=='.')
							continue;
						else if(tmpdentry->DIR_Name[x] == dest_dentry->name[j])
						{
							j++;
							break;
						}
						else
							goto continue_cmp_fail;
					}
					else
					{
						if(j < dest_dentry->nameLength && tmpdentry->DIR_Name[x] == dest_dentry->name[j])
						{
							j++;
							break;
						}
						else if(j == dest_dentry->nameLength)
							continue;
						else
							goto continue_cmp_fail;
					}

				case 'A' ... 'Z':
				case 'a' ... 'z':
					if(tmpdentry->DIR_NTRes & LOWERCASE_BASE)
						if(j < dest_dentry->nameLength && tmpdentry->DIR_Name[x] + 32 == dest_dentry->name[j])
						{
							j++;
							break;
						}
						else
							goto continue_cmp_fail;
					else
					{
						if(j < dest_dentry->nameLength && tmpdentry->DIR_Name[x] == dest_dentry->name[j])
						{
							j++;
							break;
						}
						else
							goto continue_cmp_fail;
					}

				case '0' ... '9':
					if(j < dest_dentry->nameLength && tmpdentry->DIR_Name[x] == dest_dentry->name[j])
					{
						j++;
						break;
					}
					else
						goto continue_cmp_fail;

				default :
					j++;
					break;
			}
		}
		//short file ext name compare
		if(!(tmpdentry->DIR_Attr & ATTR_DIRECTORY))
		{
			j++;
			for(x=8;x<11;x++)
			{
				switch(tmpdentry->DIR_Name[x])
				{
					case 'A' ... 'Z':
					case 'a' ... 'z':
						if(tmpdentry->DIR_NTRes & LOWERCASE_EXT)
							if(tmpdentry->DIR_Name[x] + 32 == dest_dentry->name[j])
							{
								j++;
								break;
							}
							else
								goto continue_cmp_fail;
						else
						{
							if(tmpdentry->DIR_Name[x] == dest_dentry->name[j])
							{
								j++;
								break;
							}
							else
								goto continue_cmp_fail;
						}

					case '0' ... '9':
						if(tmpdentry->DIR_Name[x] == dest_dentry->name[j])
						{
							j++;
							break;
						}
						else
							goto continue_cmp_fail;

					case ' ':
						if(tmpdentry->DIR_Name[x] == dest_dentry->name[j])
						{
							j++;
							break;
						}
						else
							goto continue_cmp_fail;

					default :
						goto continue_cmp_fail;
				}
			}
		}
		goto find_lookup_success;

continue_cmp_fail:;

	}
	
	cluster = Fat32FS::readFATEntry(fsbi,cluster);

	if(cluster < 0x0ffffff7)
		goto next_cluster;

	delete buf;

	return NULL;
find_lookup_success:

   IndexNode* p  =  (IndexNode*)new FAT32IndexNode();
   p->fileSize = tmpdentry->DIR_FileSize;
   p->blocks = (p->fileSize + fsbi->bytes_per_cluster - 1) / fsbi->bytes_per_sector;
   p->attribute = (tmpdentry->DIR_Attr & ATTR_DIRECTORY) ? FS_ATTR_DIR : FS_ATTR_FILE;
   p->sb = parent_inode->sb;

   finode =(FAT32_inode_info*) p->privateIndexInfo;
   //在哪一个簇
   finode->dentry_location = cluster;
   //第几个dirEntry
   finode->first_cluster =  (uint64_t)(((tmpdentry->DIR_FstClusHI << 16) |  (tmpdentry->DIR_FstClusLO)) & 0x0fffffff);
   finode->dentry_position = tmpdentry - (FAT32_Directory*)buf;
   finode->create_date = tmpdentry->DIR_CrtDate;
   finode->create_time = tmpdentry->DIR_CrtTime;
   finode->write_date = tmpdentry->DIR_WrtDate;
   finode->write_time = tmpdentry->DIR_WrtDate;
	
	if((tmpdentry->DIR_FstClusHI >> 12) && (p->attribute & FS_ATTR_FILE)){
		p->attribute |= FS_ATTR_DEVICE;
	} 


   dest_dentry->dirInode = p;
   delete buf;
   return dest_dentry;

}

FAT32File::FAT32File(/* args */)
{
	
}

FAT32File::~FAT32File()
{
	
}

int64_t FAT32File::open(IndexNode* inode,File* filp)
{
	
	return 1;

}

int64_t FAT32File::close(IndexNode* inode,File* filp)
{
	
	return 1;

}

int64_t FAT32File::read(char* buf, uint64_t count,int64_t* position)
{
	FAT32_inode_info* pinode =(FAT32_inode_info*)this->dentry->dirInode->privateIndexInfo;
	FAT32_sb_info* psbinfo = (FAT32_sb_info*)this->dentry->dirInode->sb->privateSbInfo;
	int64_t ret = 0;
	int64_t length = 0;
	uint64_t cluster = pinode->first_cluster;
	uint64_t nextCluster = 0;
	uint64_t sector = 0;
	int index = *position / psbinfo ->bytes_per_cluster;
	int64_t offset = *position % psbinfo->bytes_per_cluster;
	char* buffer = new char[psbinfo->bytes_per_cluster];
	
	if(!cluster)
	{
		delete buffer;
		LOG_ERROR("FAT32 FILE READ ERROR!can`t read root direntry!\n");
		return -EFAULT;

	}

	for (size_t i = 0; i < index; i++)
	{
		cluster = FAT32FILESYSTEM->readFATEntry(psbinfo,cluster);
	}
	

	if(*position + count > this->dentry->dirInode->fileSize)
		index = count = this->dentry->dirInode->fileSize - *position;
	else
		index = count;
	
	do
	{


		sector = psbinfo->Data_firstsector + (cluster - 2) * psbinfo->sector_per_cluster;


		if(!DISKMANAGER->readDisk(0x1,sector,psbinfo->sector_per_cluster,(uint8_t*)buffer)){
			
			
			LOG_ERROR("read disk error!\n");
			ret = -EIO;
			break;

		}


		length = index <= psbinfo->bytes_per_cluster - offset ? index : psbinfo->bytes_per_cluster - offset;

		if((uint64_t) buf < TASK_SPACE_SIZE && ((uint64_t)buf + count) < TASK_SPACE_SIZE)
			copy_to_user(buffer + offset,buf,length);
		else
			memcpy(buffer+offset,buf,length);


		index -=length;
		buf +=length;
		offset -= offset;
		*position += length;


	}while(index && (cluster = FAT32FILESYSTEM->readFATEntry(psbinfo,cluster)));

	delete buffer;

	if(!index)
		ret = count;

	return ret;
	
}

int64_t FAT32File::write(char* buf, uint64_t count,int64_t* position)
{

	FAT32_inode_info* pinode =(FAT32_inode_info*)this->dentry->dirInode->privateIndexInfo;
	FAT32_sb_info* psbinfo = (FAT32_sb_info*)this->dentry->dirInode->sb->privateSbInfo;
	int64_t ret = 0;
	int64_t length = 0;
	int64_t flag = 0;
	uint64_t cluster = pinode->first_cluster;
	uint64_t nextCluster = 0;
	uint64_t sector = 0;
	int index = *position / psbinfo ->bytes_per_cluster;
	int64_t offset = *position % psbinfo->bytes_per_cluster;

	char* buffer = new char[psbinfo ->bytes_per_cluster];
	
	if(!cluster){

		cluster = FAT32FILESYSTEM->findAvailableCluster(psbinfo);
		flag = 1;

	}
	else
	{
		for (size_t i = 0; i < index; i++)
		{
			cluster = FAT32FILESYSTEM->readFATEntry(psbinfo,cluster);
		}
	}
	

	if(!cluster)
	{
		delete buffer;

		return -ENOSPC;
	}

	if(flag)
	{



		pinode->first_cluster = cluster;

		this->dentry->dirInode->sb->writeInode(this->dentry->dirInode);

		FAT32FILESYSTEM->writeFATEntry(psbinfo,cluster,0x0ffffff8);


	}
	
	index = count;


	do
	{
		if(!flag)
		{
			memset(buffer,0,psbinfo->bytes_per_cluster);
			sector = psbinfo->Data_firstsector + (cluster - 2) * psbinfo->sector_per_cluster;

			if(!DISKMANAGER->readDisk(0x1,sector,psbinfo->sector_per_cluster,(uint8_t*)buffer)){
				LOG_ERROR("FAT32 FS(write) read disk ERROR!!!!!!!!!!\n");
				ret = -EIO;
				break;
			}
		}
		

		length = index <= psbinfo->bytes_per_cluster - offset ? index : psbinfo->bytes_per_cluster - offset;

		if((uint64_t) buf < TASK_SPACE_SIZE && ((uint64_t)buf + count) < TASK_SPACE_SIZE)
			copy_from_user(buf,buffer + offset,length);
		else
			memcpy(buf,buffer+offset,length);

		if(!DISKMANAGER->writeDisk(0x1,sector,psbinfo->sector_per_cluster,(uint8_t*)buffer)){

			LOG_ERROR("FAT32 FS(write) read disk ERROR!!!!!!!!!!\n");

			ret = -EIO;

			break;
		}

		index -=length;
		buf +=length;
		offset -= offset;
		*position += length;
		
		if(index)
			nextCluster = FAT32FILESYSTEM->readFATEntry(psbinfo,cluster);
		else
			break;

		if(nextCluster >= 0xfffffff8)
		{
			nextCluster = FAT32FILESYSTEM->findAvailableCluster(psbinfo);

			if(!nextCluster)
			{
				delete buffer;
				return -ENOSPC;
			}

			FAT32FILESYSTEM->writeFATEntry(psbinfo,cluster,nextCluster);
			FAT32FILESYSTEM->writeFATEntry(psbinfo,nextCluster,0x0ffffff8);

			cluster = nextCluster;
			flag = 1;
		}


	}while(index);

	if(*position > this->dentry->dirInode->fileSize){

		this->dentry->dirInode->fileSize = *position;
		this->dentry->dirInode->sb->writeInode(this->dentry->dirInode);
	}


	delete buffer;

	if(!index)
		ret = count;
	return ret;


	
}

int64_t FAT32File::lseek(int64_t offset, int64_t origin)
{
	
	uint64_t pos = 0;

	switch (origin)
	{

	case SEEK_SET:
		/* code */
		pos = offset;
		break;
	case SEEK_CUR:
		/* code */
		pos = this->position + offset;
		break;
	case SEEK_END:
		/* code */
		pos = this->dentry->dirInode->fileSize + offset;

		break;
	
	default:
		return -EINVAL;
		break;
	}


	if(pos < 0 || pos > this->dentry->dirInode->fileSize)
		return -EOVERFLOW;

	this->position = pos;

	return pos;
}

FAT32SuperBlock::FAT32SuperBlock(/* args */)
{
	privateSbInfo = (FAT32_sb_info*)new FAT32_sb_info;
	memset(privateSbInfo,0,sizeof(FAT32_sb_info));
	((FAT32_sb_info*)privateSbInfo)->fat_fsinfo = (FAT32_FSInfo*) new FAT32_FSInfo;
	memset(((FAT32_sb_info*)privateSbInfo)->fat_fsinfo,0,sizeof(FAT32_FSInfo));
	root = new FAT32DirEntry();
	list_init(&root->childNode);
	list_init(&root->subdirsList);
	root->parent = root;
	root->name = new char[2];
	memset(root->name,0,2);
	root->name[0] = '/';
	root->nameLength = 1;
	
}

FAT32SuperBlock::~FAT32SuperBlock()
{
	delete root->dirInode;
	delete root->name;
	delete root;
	delete ((FAT32_sb_info*)privateSbInfo)->fat_fsinfo;
	delete privateSbInfo;
}

FAT32IndexNode::FAT32IndexNode(/* args */)
{
	privateIndexInfo = (FAT32_inode_info*)new FAT32_inode_info;
	memset(privateIndexInfo,0,sizeof(FAT32_inode_info));
	
}

FAT32IndexNode::~FAT32IndexNode()
{
	delete privateIndexInfo;
}



/*
1.找到一个空簇
2.找到一个空entry
3.设置空簇
4.设置entry
5.返回entry
*/

DirEntry* FAT32IndexNode::create(DirEntry* dentry,char* name,uint64_t attribute)
{

	auto fsbi = (FAT32_sb_info*)dentry->dirInode->sb->privateSbInfo;
	auto finodeinfo = (FAT32_inode_info*)dentry->dirInode->privateIndexInfo;
	uint64_t nextCluster = 0;
	uint64_t sector = 0;
	uint64_t ret = 0;
	FAT32_Directory* dir = NULL;
	uint64_t cluster = finodeinfo->first_cluster;
	char* buffer = new char[fsbi->bytes_per_cluster];

	do
	{

		sector = fsbi->Data_firstsector + (cluster - 2) * fsbi->sector_per_cluster;
		if(!DISKMANAGER->readDisk(0x1,sector,fsbi->sector_per_cluster,(uint8_t*)buffer)){
			
			
			LOG_ERROR("read disk error!\n");
			ret = -EIO;
		
			delete buffer;
			return NULL;
		}


		dir = (FAT32_Directory*)buffer;
		while((dir->DIR_Attr != 0 && dir->DIR_WrtDate != 0) && dir < ((FAT32_Directory*)((uint64_t)buffer + fsbi->bytes_per_cluster))){
			dir++;
		}
		
		if(dir < ((FAT32_Directory*)((uint64_t)buffer + fsbi->bytes_per_cluster))){
			
			break;

		}

		nextCluster = FAT32FILESYSTEM->readFATEntry(fsbi,cluster);

	}while((nextCluster < 0x0ffffff8) && (cluster = nextCluster));


	
	if(nextCluster >= 0x0ffffff8)
	{

		nextCluster = FAT32FILESYSTEM->findAvailableCluster(fsbi);
		FAT32FILESYSTEM->writeFATEntry(fsbi,cluster,nextCluster);
		FAT32FILESYSTEM->writeFATEntry(fsbi,nextCluster,0xfffffff8);
		memset(buffer,0,fsbi->bytes_per_cluster);
		sector = fsbi->Data_firstsector + (nextCluster - 2) * fsbi->sector_per_cluster;
		dir = (FAT32_Directory*)buffer;

	}
	

	Path p(name);

	dir->DIR_CrtDate = 0;
	dir->DIR_CrtTime = 0;
	dir->DIR_Attr |= attribute;
	dir->DIR_FileSize = 0;
	dir->DIR_WrtDate = 0xffff;
	dir->DIR_WrtTime = 0;
	dir->DIR_LastAccDate = 0;

	
	
	uint64_t fileNameLen = strlen(p.fileName());

	if(fileNameLen >8){

		LOG_ERROR("file name is too long\n");
		delete buffer;
		return NULL;

	}

	uint64_t exeNameLen = strlen(p.fileExeName());

	if(exeNameLen >3){

		LOG_ERROR("file extend name is too long\n");
		delete buffer;
		return NULL;
		
	}	

	


	uint64_t blankLen =  8 - fileNameLen;
	
	memcpy(p.fileName(),dir->DIR_Name,fileNameLen);
	memset(dir->DIR_Name + fileNameLen,0x20,blankLen);
	memcpy(p.fileExeName(),dir->DIR_Name + 8,exeNameLen);
	



	cluster = FAT32FILESYSTEM->findAvailableCluster(fsbi);

	FAT32FILESYSTEM->writeFATEntry(fsbi,cluster,0xfffffff8);


	dir->DIR_FstClusHI =  (dir->DIR_FstClusHI & 0xf000) | (cluster >> 16) & 0xffff;
	dir->DIR_FstClusLO = cluster & 0xffff;

	if(!DISKMANAGER->writeDisk(0x1,sector,fsbi->sector_per_cluster,(uint8_t*)buffer)){

		LOG_ERROR("FAT32 FS(write) read disk ERROR!!!!!!!!!!\n");
		delete buffer;
		ret = -EIO;
		return NULL;

	}

	auto tempDentry = new FAT32DirEntry();
	tempDentry->name = new char[strlen(p.file()) + 1];
	memset(tempDentry->name,0,strlen(p.file()) + 1);
	memcpy(p.file(),tempDentry->name,strlen(p.file()));
	tempDentry->nameLength = strlen(p.file());

	auto temp = lookup(dentry->dirInode,tempDentry);


	if(!temp){

		LOG_ERROR("create file error!can`t find created file!\n");
		delete tempDentry;
		delete buffer;
		return NULL;

	}
	delete buffer;
	return temp;
}	

FAT32DirEntry::FAT32DirEntry(/* args */)
{	
	
	dirInode = new FAT32IndexNode();

	
}

FAT32DirEntry::~FAT32DirEntry()
{
	delete dirInode;
}
